use std::collections::HashMap;

pub trait Server {
    fn handle_request(&mut self, url: String, method: String) -> (i32, &str);
}

struct Application {}

impl Server for Application {
    fn handle_request(&mut self, url: String, method: String) -> (i32, &str) {
        if url == "/app/status" && method == "GET" {
            return (200, "Ok");
        }
        if url == "/create/user" && method == "POST" {
            return (201, "User Created");
        }
        return (404, "Not Ok");
    }
}


struct Nginx {
    application: Application,
    max_allowed_request: i32,
    rate_limiter: HashMap<String, i32>,
}

fn newNginxServer() -> Nginx {
    return Nginx {
        application: Application {},
        max_allowed_request: 0,
        rate_limiter: HashMap::new(),
    };
}


impl Server for Nginx {
    fn handle_request(&mut self, url: String, method: String) -> (i32, &str) {
        let x = self.check_rate_limiting(url.clone());
        if !x {
            return (403, "Not Allowed");
        }
        return self.application.handle_request(url, method);
    }
}

impl Nginx {
    fn check_rate_limiting(&mut self, url: String) -> bool {
        if self.rate_limiter[&url] == 0 {
            self.rate_limiter.insert(url.clone(), 1);
        };
        if self.rate_limiter[&url] > self.max_allowed_request {
            return false;
        };
        self.rate_limiter.insert(url.clone(), self.rate_limiter[&url] + 1);
        return true;
    }
}


#[cfg(test)]
mod chain {
    #[test]
    fn main() {}
}